package com.estate.common.utils;

import com.estate.common.config.TimeZoneConfig;

import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.Date;

/**
 * 统一时间处理工具类
 */
public class TimeZoneUtils {

    // 统一格式化器
    private static final DateTimeFormatter ISO_FORMATTER = DateTimeFormatter.ISO_DATE_TIME;
    private static final DateTimeFormatter DISPLAY_FORMATTER =
            DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    /**
     * 获取当前系统时间（悉尼时区）
     */
    public static LocalDateTime now() {
        return LocalDateTime.now(TimeZoneConfig.SYSTEM_ZONE);
    }

    /**
     * 获取当前UTC时间
     */
    public static LocalDateTime nowUTC() {
        return LocalDateTime.now(TimeZoneConfig.SERVER_ZONE);
    }

    /**
     * 将任意时间转换为系统时间（悉尼时区）
     */
    public static LocalDateTime toSystemTime(String iso8601Time) {
        if (iso8601Time == null) return null;

        try {
            ZonedDateTime zonedTime = ZonedDateTime.parse(iso8601Time);
            return zonedTime.withZoneSameInstant(TimeZoneConfig.SYSTEM_ZONE)
                    .toLocalDateTime();
        } catch (Exception e) {
            // 尝试其他解析方式
            return tryAlternativeParse(iso8601Time);
        }
    }

    /**
     * 系统时间转换为UTC时间（用于数据库存储）
     */
    public static LocalDateTime toUTCTime(LocalDateTime systemTime) {
        if (systemTime == null) return null;

        ZonedDateTime zonedSystemTime = systemTime.atZone(TimeZoneConfig.SYSTEM_ZONE);
        return zonedSystemTime.withZoneSameInstant(TimeZoneConfig.SERVER_ZONE)
                .toLocalDateTime();
    }

    /**
     * UTC时间转换为系统时间（用于数据读取）
     */
    public static LocalDateTime fromUTCTime(LocalDateTime utcTime) {
        if (utcTime == null) return null;

        ZonedDateTime zonedUTCTime = utcTime.atZone(TimeZoneConfig.SERVER_ZONE);
        return zonedUTCTime.withZoneSameInstant(TimeZoneConfig.SYSTEM_ZONE)
                .toLocalDateTime();
    }

    /**
     * 系统时间转换为展示时间（北京时间）
     */
    public static LocalDateTime toDisplayTime(LocalDateTime systemTime) {
        if (systemTime == null) return null;

        ZonedDateTime zonedSystemTime = systemTime.atZone(TimeZoneConfig.SYSTEM_ZONE);
        return zonedSystemTime.withZoneSameInstant(TimeZoneConfig.DISPLAY_ZONE)
                .toLocalDateTime();
    }

    /**
     * 格式化为展示字符串（北京时间）
     */
    public static String formatDisplayTime(LocalDateTime systemTime) {
        LocalDateTime displayTime = toDisplayTime(systemTime);
        return displayTime != null ? displayTime.format(DISPLAY_FORMATTER) : null;
    }

    private static LocalDateTime tryAlternativeParse(String timeString) {
        try {
            // 尝试解析为Instant
            Instant instant = Instant.parse(timeString);
            return LocalDateTime.ofInstant(instant, TimeZoneConfig.SYSTEM_ZONE);
        } catch (Exception e) {
            // 最后尝试LocalDateTime（假设已经是系统时区）
            return LocalDateTime.parse(timeString, ISO_FORMATTER);
        }
    }

    /**
     * 检查当前是否悉尼夏令时
     */
    public static boolean isSydneyDaylightSaving() {
        return TimeZoneConfig.SYSTEM_ZONE.getRules()
                .isDaylightSavings(Instant.now());
    }

    /**
     * 获取悉尼与UTC的当前时差
     */
    public static String getSydneyUTCOffset() {
        ZoneOffset offset = TimeZoneConfig.SYSTEM_ZONE.getRules()
                .getOffset(Instant.now());
        return offset.toString();
    }


    private static final ZoneId ZONE_BEIJING = ZoneId.of("Asia/Shanghai");
    private static final ZoneId ZONE_SYDNEY  = ZoneId.of("Australia/Sydney");

    /* 1. 当前北京时间 → 悉尼时间字符串（yyyy-MM-dd HH:mm:ss） */
    public static String nowBeijingToSydneyStr() {
        return ZonedDateTime.now(ZONE_BEIJING)
                .withZoneSameInstant(ZONE_SYDNEY)
                .format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
    }

    /* 1. 当前北京时间 → 悉尼时间 Date（用于旧代码） */
    public static Date nowBeijingDateToSydneyDate() {
        return Date.from(
                ZonedDateTime.now(ZoneId.of("Asia/Shanghai"))   // 当前北京时间
                        .withZoneSameInstant(ZoneId.of("Australia/Sydney"))
                        .toInstant()
        );
    }

    /* 2. 北京时间字符串 → 悉尼时间字符串（格式可自定义） */
    public static String bjStrToSydneyStr(String beijingStr, String pattern) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
        LocalDateTime bjDateTime = LocalDateTime.parse(beijingStr, formatter);
        ZonedDateTime bjZoned = bjDateTime.atZone(ZONE_BEIJING);
        return bjZoned.withZoneSameInstant(ZONE_SYDNEY)
                .format(formatter);
    }

    /* 3. 北京 Date → 悉尼 Date（遗留代码需要 Date 时用） */
    public static Date bjDateToSydneyDate(Date beijingDate) {
        Instant instant = beijingDate.toInstant();                 // Date 总是 UTC 瞬时
        ZonedDateTime bjZoned = instant.atZone(ZONE_BEIJING);      //告诉它这是北京时区
        ZonedDateTime sydneyZoned = bjZoned.withZoneSameInstant(ZONE_SYDNEY);
        return Date.from(sydneyZoned.toInstant());                 // 再变回 Date
    }
}